/*
 * Copyright (c) 2017-2019, Lindenis Tech. Ltd.
 * All rights reserved.
 *
 * File:
 *
 * Description:
 *
 * Author:
 *      xiaoshujun@lindeni.com
 *
 * Create Date:
 *      2019/08/08
 *
 * History:
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#include "osal_mutex.h"

OSAL_mutex * OSAL_CreateMutex()
{
    OSAL_mutex *mutex;

    /* Allocate the structure */
    mutex = (OSAL_mutex *) malloc(sizeof(OSAL_mutex));
    if (mutex) {
        if (pthread_mutex_init(&mutex->id, NULL) != 0) {
            free(mutex);
            mutex = NULL;
        }
    }

    return (mutex);
}

int OSAL_DestroyMutex(OSAL_mutex * mutex)
{
    if (!mutex)
        return ErrorUnknown;

    pthread_mutex_destroy(&mutex->id);
    free(mutex);

    return ErrorNone;
}

int OSAL_LockMutex(OSAL_mutex * mutex)
{
    if (!mutex)
        return ErrorUnknown;

    if (pthread_mutex_lock(&mutex->id) != 0) {
        return ErrorUnknown;
    }

    return ErrorNone;
}

int OSAL_TryLockMutex(OSAL_mutex * mutex)
{
    if (!mutex)
        return ErrorUnknown;

    return pthread_mutex_trylock(&mutex->id);
}

int OSAL_UnlockMutex(OSAL_mutex * mutex)
{
    if (!mutex)
        return ErrorUnknown;

    return pthread_mutex_unlock(&mutex->id);
}

#ifndef MELIS_OS
int OSAL_MutexCreate(HANDLETYPE *mutexHandle)
{
    pthread_mutex_t *mutex;

    mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
    if (!mutex)
        return ErrorUnknown;

    if (pthread_mutex_init(mutex, NULL) != 0) {
        return ErrorUnknown;
    }

    *mutexHandle = (HANDLETYPE)mutex;
    return ErrorNone;
}

int OSAL_MutexTerminate(HANDLETYPE mutexHandle)
{
    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;

    if (mutex == NULL)
        return ErrorUnknown;

    if (pthread_mutex_destroy(mutex) != 0) {
        return ErrorUnknown;
    }

	if (mutex)
    	free(mutex);
    return ErrorNone;
}

int OSAL_MutexLock(HANDLETYPE mutexHandle)
{
    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;
    int result;

    if (mutex == NULL)
        return ErrorUnknown;

    if (pthread_mutex_lock(mutex) != 0) {
        return ErrorUnknown;
    }

    return ErrorNone;
}

int OSAL_MutexUnlock(HANDLETYPE mutexHandle)
{
    pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle;
    int result;

    if (mutex == NULL)
        return ErrorUnknown;

    if (pthread_mutex_unlock(mutex) != 0) {
        return ErrorUnknown;
    }

    return ErrorNone;
}
#endif
